﻿using System;

using Scope = System.Collections.IDictionary;

namespace Sencha.Serialization.Bson.Serializers
{
	public sealed class BsonJavaScriptWithScopeSerializer : TypeSerializer<BsonJavaScriptWithScope>
	{
		public override BsonJavaScriptWithScope Deserialize(IJsonReader reader)
		{
			if (reader == null)
				throw new ArgumentNullException("reader");

			if (reader is IBsonReader)
				return this.DeserializeBson(reader as IBsonReader);

			reader.ReadObjectBegin();
			var code = reader.ReadMember<string>("$code");
			var scope = reader.ReadMember<Scope>("$scope");
			reader.ReadObjectEnd(false);

			var value = new BsonJavaScriptWithScope(code, scope);
			return value;
		}
		private BsonJavaScriptWithScope DeserializeBson(IBsonReader reader)
		{

			if (reader.Token != BsonToken.JavaScriptWithScope)
				throw new Exceptions.UnexpectedBsonToken(reader, BsonToken.JavaScriptWithScope);

			var js = (BsonJavaScriptWithScope)reader.Value.Raw;
			var scope = reader.ReadValue<Scope>(false);

			var value = new BsonJavaScriptWithScope(js.Code, scope);
			return value;
		}

		public override void Serialize(IJsonWriter writer, BsonJavaScriptWithScope value)
		{
			if (writer == null)
				throw new ArgumentNullException("writer");

			if (value == null)
			{
				writer.WriteNull();
				return;
			}

			if (writer is IBsonWriter)
			{
				this.SerializeBson(writer as IBsonWriter, value);
				return;
			}

			writer.WriteObjectBegin();
			writer.WriteMember<string>("$code", value.Code);
			writer.WriteMember<Scope>("$scope", value.Scope);
			writer.WriteObjectEnd();
		}
		private void SerializeBson(IBsonWriter writer, BsonJavaScriptWithScope value)
		{
			writer.Write(BsonToken.JavaScriptWithScope, value);			
			writer.WriteValue(value.Scope);
			writer.Write(BsonToken.EndOfDocument, (object)null);
		}
	}
}
